
#include "Ini.h"
#include "myLog.h"

#define SECTION_MAX_LEN 256
#define STRVALUE_MAX_LEN 256
#define LINE_CONTENT_MAX_LEN 256

static void IniReadValue(char* section, char* key, char* val, const char* file);
static void IniWriteValue(const char* section, char* key, char* val, const char* file);

/**
 * @description: 外部调用，读取配置文件中的string数据
 * @param {char} *section节点
 * @param {char} *key关键词
 * @param {char} *val输出字符串
 * @param {char} *file文件路径
 * @return {*} 0
 */
int readStringValue(const char *section, char *key, char *val, const char *file)
{
    char sect[SECTION_MAX_LEN];
    // printf("section = %s, key = %s, file = %s\n", section, key, file);
    if (section == NULL || key == NULL || val == NULL || file == NULL)
    {
        qlog_e("%s: input parameter(s) is NULL!\n", __func__);
        return INI_NO_ATTR;
    }

    memset(sect, 0, SECTION_MAX_LEN);
    sprintf(sect, "[%s]", section);
    // printf("reading value...\n");
    IniReadValue(sect, key, val, file);

    return INI_SUCCESS;
}
/**
 * @description: 外部调用，读取配置文件里的int数据
 * @param {char} *section
 * @param {char} *key
 * @param {char} *file
 * @return {*}
 */
int readIntValue(const char *section, char *key, const char *file)
{
    char strValue[STRVALUE_MAX_LEN];
    memset(strValue, '\0', STRVALUE_MAX_LEN);
    if (readStringValue(section, key, strValue, file) != INI_SUCCESS)
    {
        qlog_e("%s: error", __func__);
        return -1;
    }
    return (atoi(strValue));
}


/**
 * @description: 外部调用写入string
 * @param {char} *section
 * @param {char} *key
 * @param {char} *val
 * @param {char} *file
 * @return {*}
 */
int writeStringVlaue(const char *section, char *key, char *val, const char *file)
{
    char sect[SECTION_MAX_LEN];
    // printf("section = %s, key = %s, file = %s\n", section, key, file);
    if (section == NULL || key == NULL || val == NULL || file == NULL)
    {
        qlog_e("%s: input parameter(s) is NULL!\n", __func__);
        return INI_NO_ATTR;
    }
    memset(sect, '\0', SECTION_MAX_LEN);
    sprintf(sect, "[%s]", section);
    IniWriteValue(sect, key, val, file);
    return 0;
}
/**
 * @description: 外部调用写入int
 * @param {char} *section
 * @param {char} *key
 * @param {int} val
 * @param {char} *file
 * @return {*}
 */
int writeIntValue(const char *section, char *key, int val, const char *file)
{
    char strValue[STRVALUE_MAX_LEN];
    memset(strValue, '\0', STRVALUE_MAX_LEN);
    sprintf(strValue, "%-4d", val);

    return writeStringVlaue(section, key, strValue, file);
}


/**
 * @description: 内部调用，读出int值read value from .ini
 * @param {char} *section
 * @param {char} *key
 * @param {char} *val
 * @param {char} *file
 * @return {*}
 */
static void IniReadValue(char *section, char *key, char *val, const char *file)
{
    FILE *fp;
    int i = 0;
    int lineContentLen = 0;
    int position = 0;
    char lineContent[LINE_CONTENT_MAX_LEN];
    bool bFoundSection = false;
    bool bFoundKey = false;
    fp = fopen(file, "r");
    if (fp == NULL)
    {
        qlog_e("%s: Opent file %s failed.\n", __FILE__, file);
        return;
    }
    while (feof(fp) == 0)
    {
        memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
        fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
        if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
        {
            continue;
        }

        // check section
        if (strncmp(lineContent, section, strlen(section)) == 0)
        {
            bFoundSection = true;
            // printf("Found section = %s\n", lineContent);
            while (feof(fp) == 0)
            {
                memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
                fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
                // check key
                if (strncmp(lineContent, key, strlen(key)) == 0)
                {
                    bFoundKey = true;
                    lineContentLen = strlen(lineContent);
                    // find value
                    for (i = strlen(key); i < lineContentLen; i++)
                    {
                        if (lineContent[i] == '=')
                        {
                            position = i + 1;
                            break;
                        }
                    }
                    if (i >= lineContentLen)
                        break;
                    strncpy(val, lineContent + position, strlen(lineContent + position));
                    lineContentLen = strlen(val);
                    for (i = 0; i < lineContentLen; i++)
                    {
                        if ((lineContent[i] == '\0') || (lineContent[i] == '\r') || (lineContent[i] == '\n'))
                        {
                            val[i] = '\0';
                            break;
                        }
                    }
                }
                else if (lineContent[0] == '[')
                {
                    break;
                }
            }
            break;
        }
    }
    if (!bFoundSection)
    {
        qlog_e("No section = %s\n", section);
    }
    else if (!bFoundKey)
    {
        qlog_e("No key = %s\n", key);
    }
    fclose(fp);
}

/**
 * @description: 内部调用，写入int
 * @param {char} *section
 * @param {char} *key
 * @param {char} *val
 * @param {char} *file
 * @return {*}
 */
static void IniWriteValue(const char *section, char *key, char *val, const char *file)
{
    FILE *fp;
    int err = 0;
    char lineContent[LINE_CONTENT_MAX_LEN];
    char strWrite[LINE_CONTENT_MAX_LEN];
    bool bFoundSection = false;
    bool bFoundKey = false;

    memset(lineContent, '\0', LINE_CONTENT_MAX_LEN);
    memset(strWrite, '\0', LINE_CONTENT_MAX_LEN);
    sprintf(strWrite, "%s=%s\n", key, val);
    fp = fopen(file, "r+");
    if (fp == NULL)
    {
        qlog_e("%s: Opent file %s failed.\n", __FILE__, file);
        return;
    }
    while (feof(fp) == 0)
    {
        memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
        fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
        if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
        {
            continue;
        }
        // check section
        if (strncmp(lineContent, section, strlen(section)) == 0)
        {
            bFoundSection = true;
            while (feof(fp) == 0)
            {
                memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
                fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
                // check key
                if (strncmp(lineContent, key, strlen(key)) == 0)
                {
                    bFoundKey = true;
                    qlog_i("%s: %s=%s\n", __func__, key, val);
                    fseek(fp, (0 - strlen(lineContent)), SEEK_CUR);
                    err = fputs(strWrite, fp);
                    if (err < 0)
                    {
                        qlog_e("%s err.\n", __func__);
                    }
                    break;
                }
                else if (lineContent[0] == '[')
                {
                    break;
                }
            }
            break;
        }
    }
    if (!bFoundSection)
    {
        qlog_e("No section = %s\n", section);
    }
    else if (!bFoundKey)
    {
        qlog_e("No key = %s\n", key);
    }
    fclose(fp);
}